﻿using ImperialServer.Common.Entities;
using ImperialServer.Data.DAO;
using ImperialServer.Data.Interfaces;
using ImperialUtilities.Exceptions;
using ImperialUtilities.Utilities;
using ImperialWebSite.Content.Resources;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;

namespace ImperialWebSite.Controllers
{
    public class RoleController : BaseController
    {
        private IRegistryAccess _daoRegistryAccess;
        private EventViewer _logger;

        public RoleController()
        {
            _logger = new EventViewer("ImperialWebSite.Controllers");
            _daoRegistryAccess = new RegistryAccess(ConfigurationManager.ConnectionStrings["ImperialConnection"].ConnectionString);
        }

        /// <summary>
        /// Metodo que crea un objeto de tipo RoleEntity
        /// </summary>
        /// <param name="roleNameText">nombre del rol</param>
        /// <returns>objeto lleno</returns>
        internal RoleEntity CreateNewRole(string roleNameText)
        {
            RoleEntity newRole = null;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "CreateNewRole"));

                newRole = new RoleEntity
                    {
                        RoleName = roleNameText
                    };

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("CreateNewRole", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "CreateNewRole"));
            }
            return newRole;
        }

        /// <summary>
        /// Metodo que se encarga de realizar la llamada al servidor para insertar un nuevo rol
        /// </summary>
        /// <param name="newRole">objeto con los datos a insertar</param>
        /// <returns>true si fue exitosa, false si no</returns>
        internal bool InsertNewRole(RoleEntity newRole)
        {
            bool isSuccess = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "InsertNewRole"));

                isSuccess = _daoRegistryAccess.InsertNewRole(newRole);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("InsertNewRole", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "InsertNewRole"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que indica si un roleName ya se encuentra registrado
        /// </summary>
        /// <param name="roleName">nombre de rol</param>
        /// <param name="currentRoles">lista de roles ya registrados</param>
        /// <returns>true si existe, false si no</returns>
        internal bool RoleAlreadyRegistered(string roleName, object currentRoles)
        {
            bool found = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "RoleAlreadyRegistered"));

                DataTable dtCurrentRoles = (DataTable)currentRoles;
                DataRow[] drCurrentRole = dtCurrentRoles.Select("roleName = '" + roleName.ToLower() + "'");
                found = drCurrentRole != null && drCurrentRole.Length > 0;

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("RoleAlreadyRegistered", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "RoleAlreadyRegistered"));
            }
            return found;
        }

        /// <summary>
        /// Metodo que se encarga de hacer la llamada al servidor para actualizar la informacion de un rol
        /// </summary>
        /// <param name="roleName">objeto con los datos a actualizar</param>
        /// <returns>true si es exitosa, false si no</returns>
        internal bool UpdateRole(RoleEntity role)
        {
            bool isSuccess = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "UpdateRole"));

                isSuccess = _daoRegistryAccess.UpdateRole(role);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("UpdateRole", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "UpdateRole"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que se encarga de consultar un registro para saber si es igual a un parametro
        /// </summary>
        /// <param name="roleName">nombre de rol</param>
        /// <param name="currentRoles">coleccion de registros</param>
        /// <param name="currentRole">registro a consultar</param>
        /// <returns>true si es el mismo registro, false si no</returns>
        internal bool IsTheSameRole(string roleName, object currentRoles, object currentRole)
        {
            bool isSameRole = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "IsTheSameRole"));

                DataTable dtCurrentRoles = (DataTable)currentRoles;
                DataRow[] drCurrentRole = dtCurrentRoles.Select("idRole = " + currentRole.ToString());
                if (drCurrentRole != null && drCurrentRole.Length > 0)
                    isSameRole = drCurrentRole[0]["roleName"].ToString() == roleName;
                else
                {
                    _logger.WriteEventViewerLog("IsTheSameRole", Messages.failureTransactionMessage, true);
                    throw new ImperialException(Messages.failureTransactionMessage);
                }

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("IsTheSameRole", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "IsTheSameRole"));
            }
            return isSameRole;
        }
    }
}